//
//  VIPAgoraManager.m
//  TTProduct
//
//  Created by My mac on 2019/7/30.
//  Copyright © 2019年 TTProduct. All rights reserved.
//

#import "VIPAgoraManager.h"
#import "VIPPCH.h"

@interface VIPAgoraManager ()

@property (nonatomic, strong) AgoraAPI *signaling;
@property (strong, nonatomic) NSMutableDictionary *messageDictionary;

@end

@implementation VIPAgoraManager

- (void)registerSignalingSDK:(VIPSignalModel *)signal {
    self.status = VIPSignalStateLoginNO;
    
    [super registerSignalingSDK:signal];
    
    self.signaling = [AgoraAPI getInstanceWithoutMedia:signal.appId];
    
    // 频道内
    WS(weakSelf)
    [self.signaling setOnMessageChannelReceive:^(NSString *channelID, NSString *account, uint32_t uid, NSString *msg) {
        
        NSLog(@"channelID: %@", channelID);
        NSLog(@"account: %@", account);
        NSLog(@"msg: %@", msg);
        if(msg.length == 0) return;
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (weakSelf.status == VIPSignalStateLogout) return;
            if (account.integerValue == [signal.account integerValue]) return;
            if (!weakSelf.response) return;
            weakSelf.response(account, msg, weakSelf.signaingName);
        });
    }];
}

- (void)loginCompletion:(VIPCompletionHandler)completion {
    self.status = VIPSignalStateLoginNO;
    [self.signaling login2:self.signal.appId
                   account:self.signal.account
                     token:self.signal.token
                       uid:0 deviceID:@""
           retry_time_in_s:30
               retry_count:0];
    self.status = VIPSignalStateLogining;
    WS(weakSelf)
    //登录成功
    [self.signaling setOnLoginSuccess:^(uint32_t uid, int fd) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnLoginSuccess] - vendor:%@, code: %d", __func__, weakSelf.signaingName, (int)fd];
            if (!completion) return;
            completion(nil);
        });
    }];
    
    //登录失败
    [self.signaling setOnLoginFailed:^(AgoraEcode ecode) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (ecode == AgoraEcode_LOGIN_E_TOKENEXPIRED) {
                weakSelf.status = VIPSignalStateLoginNO;
                if (!weakSelf.tokenDidFailure) return ;
                weakSelf.tokenDidFailure();
                return ;
            }
            
            weakSelf.status = VIPSignalStateLoginFailed;
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnLoginFailed] - vendor:%@, code: %d", __func__, weakSelf.signaingName, (int)ecode];
            if (!completion) return;
            VIPMessage *message = [weakSelf messageWithEcode:ecode];
            message.ecode = ecode;
            completion(message);
        });
    }];
    
    [self.signaling setOnError:^(NSString *name, AgoraEcode ecode, NSString *desc) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (ecode == AgoraEcode_LOGIN_E_TOKENEXPIRED) {
                weakSelf.status = VIPSignalStateLoginNO;
                if (!weakSelf.tokenDidFailure) { return ; }
                weakSelf.tokenDidFailure();
                return ;
            }
        });
    }];
}

- (void)relogin:(VIPCompletionHandler)completion {
    WS(weakSelf)
    [self loginCompletion:^(VIPMessage * _Nonnull message) {
        if (message == nil) {
            [weakSelf rejoinroom:^(VIPMessage * _Nullable message) {
                if (completion) return completion(message);
            }];
            return;
        }
        // 被踢
        if (message.status == VIPSignalCodeKiched) {
            if (!completion) return;
            completion(message);
            return;
        }
        
        [weakSelf relogin:completion];
    }];
}

- (void)rejoinroom:(VIPCompletionHandler)completion {
    WS(weakSelf)
    [self joinRoomCompletion:^(VIPMessage * _Nullable message) {
        if (message) {
            [weakSelf relogin:completion];
            return;
        }
        if (completion) return completion(nil);
    }];
}

- (void)loginedLostConnectionCompletion:(VIPCompletionHandler)completion {
    WS(weakSelf)
    //登录之后，失去和服务器的连接/ 被踢
    [self.signaling setOnLogout:^(AgoraEcode ecode) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnLogout] - vendor:%@, code: %d", __func__, weakSelf.signaingName, (int)ecode];
            
            VIPMessage *message = [weakSelf messageWithEcode:ecode];
            
            if (ecode == AgoraEcode_LOGOUT_E_TOKENEXPIRED) {
                if (!weakSelf.tokenDidFailure) return ;
                weakSelf.tokenDidFailure();
                return ;
            }
            
            if (ecode != AgoraEcode_LOGOUT_E_KICKED && weakSelf.status != VIPSignalStateLogout) {
                [weakSelf relogin:completion];
            }
            
            if (ecode != AgoraEcode_LOGOUT_E_USER) {
                weakSelf.status = VIPSignalStateLoseConnection;
            }
            if (ecode == AgoraEcode_LOGOUT_E_KICKED) {
                weakSelf.status = VIPSignalStateKiched;
            }
            
            message.ecode = ecode;
            if (!completion) return;
            completion(message);
        });
    }];
}

- (void)joinRoomCompletion:(VIPCompletionHandler)completion {
    [self.signaling channelJoin:self.signal.roomId];
    WS(weakSelf)
    // 加入房间成功
    [self.signaling setOnChannelJoined:^(NSString *channelID) {
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.status = VIPSignalStateLoginOK;
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnChannelJoined] - success", __func__];
            if (completion) completion(nil);
        });
    }];
    
    // 加入房间失败
    [self.signaling setOnChannelJoinFailed:^(NSString *channelID, AgoraEcode ecode) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnChannelJoinFailed] - ecode: %d", __func__, (int)ecode];
            
            if (!completion) return;
            VIPMessage *message = [weakSelf messageWithEcode:ecode];
            completion(message);
        });
    }];
}

- (void)sendMessageCompletion:(VIPCompletionHandler)completion {
    [self.signaling messageChannelSend:self.signal.roomId msg:self.signal.msg msgID:nil];
    WS(weakSelf)
    //发送成功
    [self.signaling setOnMessageSendSuccess:^(NSString *messageID) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnMessageSendSuccess] - msg: %@", __func__, weakSelf.signal.msg];
            
            if (!completion) {return; }
            completion(nil);
        });
    }];
    
    //失败
    [self.signaling setOnMessageSendError:^(NSString *messageID, AgoraEcode ecode) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [VIPWrite writeLogWithFormat:@"%s [signaling setOnMessageSendError] - msg: %@, code:%d", __func__, weakSelf.signal.msg, (int)ecode];
            
            if (!completion) {return; }
            VIPMessage *message = [weakSelf messageWithEcode:ecode];
            completion(message);
        });
    }];
}

- (void)leaveRoomCompletion:(VIPCompletionHandler)completion {
    if(completion) completion(nil);
}

- (void)logoutCompletion:(VIPCompletionHandler)completion {
    self.status = VIPSignalStateLogout;
    [self.signaling logout];
    //此方法释放 Agora SDK 使用的所有资源，用户将无法再使用和回调该 SDK 内的其它方法
    //且是同步调用，资源释放后返回
    [self.signaling destroy];
}

- (VIPMessage *)messageWithEcode:(AgoraEcode)ecode {
    if(ecode == AgoraEcode_SUCCESS ||
       ecode == AgoraEcode_LOGIN_E_ALREADY_LOGIN) {
        return nil;
    }
    
    if (ecode == AgoraEcode_LOGOUT_E_KICKED) {
        return [VIPMessage messageWithFailedText:@"声网 : 在别的地方登陆" status:VIPSignalCodeKiched];
    }
    
    if(ecode == AgoraEcode_LOGOUT_E_USER) {
        return [VIPMessage messageWithFailedText:@"用户退出" status:VIPSignalCodeLogout];
    }
    return [VIPMessage messageWithFailedText:@"未知原因" status:VIPSignalCodeOther];
}

// 初始化单粒
static VIPAgoraManager* _instance = nil;
+ (instancetype)shareManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init];
    });
    return _instance ;
}

+ (id)allocWithZone:(struct _NSZone *)zone {
    return [VIPAgoraManager shareManager];
}

- (id)copyWithZone:(struct _NSZone *)zone {
    return [VIPAgoraManager shareManager];
}

- (NSString *)flag {
    return @"A";
}

- (NSString *)signaingName {
    return @"声网";
}

@end
